from fastapi import File,UploadFile
from utils.encrypto import create_md5
import time
import aiofiles,os
async def maxFileWriter(
    filename: str, 
    foldersPath: str, 
    total_chunks: int, 
    chunk_number: int, 
    chunk: UploadFile = File(...)
)->dict:
    """
    :param filename:  文件名
    :param foldersPath: 文件夹路径
    :param total_chunks: 文件总数量
    :param chunk_number: 文件请求序号
    :param chunk: 文件分块主体
    :return:
    """
    fileSign = create_md5(filename)
    chunk_path = os.path.join(foldersPath, f"{fileSign}_{chunk_number}")
    final_path = os.path.join(foldersPath, filename)
    try:
        content = await chunk.read()
        async with aiofiles.open(chunk_path, 'wb') as f:
            await f.write(content)

        if chunk_number == total_chunks:
            total_chunks=total_chunks+1

            missing_chunks = [
                i for i in range(1, total_chunks)
                if not os.path.exists(os.path.join(foldersPath, f"{fileSign}_{i}"))
            ]

            if missing_chunks:
                await cleanup_chunks(fileSign, foldersPath, total_chunks)
                return dict(code=400, message=f"文件校验错误，缺失分片: {missing_chunks}")
            async with aiofiles.open(final_path, 'wb') as final_file:
                for i in range(1, total_chunks):
                    part_path = os.path.join(foldersPath, f"{fileSign}_{i}")
                    async with aiofiles.open(part_path, 'rb') as part_file:
                        await final_file.write(await part_file.read())
                    os.remove(part_path)
            return dict(message="大文件上传成功", data={"total_chunks": total_chunks, "chunk_number": chunk_number})
        return dict(message="分片上传成功", data={"chunk_number": chunk_number})
    except Exception as e:
        await cleanup_chunks(fileSign, foldersPath, total_chunks)
        return dict(code=500, message=f"文件上传失败: {str(e)}")


async def cleanup_chunks(fileSign: str, foldersPath: str, total_chunks: int):
    for i in range(1, total_chunks + 1):
        chunk_path = os.path.join(foldersPath, f"{fileSign}_{i}")
        if os.path.exists(chunk_path):
            os.remove(chunk_path)
